﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using YinfangWeb.BLL.Enum;
using YinfangWeb.BLL.Model;
using YinfangWeb.Common;
using YinfangWeb.DAL;
using YinfangWeb.Model;

namespace YinfangWeb.BLL
{
    public class ProductBO
    {
        private readonly string HttpBaseUrl = ConfigurationManager.AppSettings["HttpFileBaseUrl"];
        private readonly FileServer _FileServer = new FileServer();
        private readonly ProductDataDAO _pDataDAO = new ProductDataDAO();
        private readonly ProductParamDAO _pParamDAO = new ProductParamDAO();
        private readonly ProductFileDAO _pFileDAO = new ProductFileDAO();
        private readonly ProductKindDAO _pKindDAO = new ProductKindDAO();

        //创建商品：生成一个存入商品的记录，分配一个唯一的商品编号
        public IResult CreateProduct(ProductData pData,ProductParam pParam)
        {
            using (var conn = ConnectionFactory.CreateConnection())
            {
                conn.Open();
                var trans = conn.BeginTransaction();
                try
                {
                    pData.TotalStock = pParam.Stock;//母板库存就是总库存
                    if (pData.ProductDataID == 0)//新增商品
                    {                        
                        _pDataDAO.Insert(pData, trans);//生成新商品基本数据
                        pParam.ProductDataID = pData.ProductDataID;
                        _pParamDAO.Insert(pParam, trans);//生成新商品的母板数据
                    }
                    else//保存修改后的商品
                    {
                        _pDataDAO.UpdateNotInfo(pData, trans);//不修改商品介绍字段(单独修改)
                        _pParamDAO.UpdateNotDefaultFileID(pParam, trans);//不修改默认图标文件ID
                    }
                    trans.Commit();
                    //为上传图片创建对应目录
                    new FileServer().CreateDir(pData.ProductDataID);
                    //返回新商品的ID和NO
                    var result = new ObjProductCreateResult
                    {
                        ProductDataID = pData.ProductDataID,
                        ProductParamID=pParam.ProductParamID
                    };
                    return new DataResult<ObjProductCreateResult>(result);
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    throw (ex);
                }
                finally
                {
                    conn.Close();
                }
            }            
        }
        //登记上传的单个商品图片
        public int AddProductFile(int spId,string newFileName,EnumProductFile_FileType fileType,EnumProductFile_ViewLogo viewLogo)
        {
            var spFile = new ProductFile
            {
                ProductDataID = spId,
                FileType = (int)fileType,
                ViewLogo = (int)viewLogo,
                ViewOrder = 0,
                FileName = newFileName
            };
            _pFileDAO.Insert(spFile);
            //为属性参数母板指定一个默认Logo:第一个上传成功的
            SaveProductDefaultLogoFileID(spId, spFile.ProductFileID);//没有才填写
            return 1;
        }
        //处理商品Logo的排序与删除
        public IResult UpdateProductLogoList(int spId,List<string> logoList)
        {            
            var oldLogoList = _pFileDAO.GetListBySpID(spId,(int)EnumProductFile_FileType.Image,(int)EnumProductFile_ViewLogo.Yes);
            List<string> oldList = oldLogoList.Select(logo => logo.FileName).ToList();//已上传的
            List<string> delLogoList = oldList.Except(logoList).ToList();//要删除的
            delLogoList.ForEach(logo =>
            {
                _FileServer.DeleteSpFile(spId.ToString(), logo, EnumProductFile_ViewLogo.Yes);
                _pFileDAO.Delete(spId, logo);
                int at = oldLogoList.FindIndex(lg => lg.FileName == logo);
                oldLogoList.RemoveAt(at);
            });
            var spInfo = _pDataDAO.GetInfo(spId);
            if (oldLogoList.Count > 0)
            {
                for (var i = 0; i < logoList.Count; i++)
                {
                    int at = oldLogoList.FindIndex(lg => lg.FileName == logoList[i]);
                    oldLogoList[at].ViewOrder = i;
                }
                _pFileDAO.Update(oldLogoList);
                //将排列在第一个的图片作为商品的默认图标
                var first = oldLogoList.OrderBy(lg => lg.ViewOrder).Take(1).ToList()[0];
                SaveProductDefaultLogoFileID(spId, first.ProductFileID,false);//覆盖   
            }
            else
            {
                //所有图标删除完了，清除商品的默认图标
                //spInfo.DefaultProductFileID = 0;
            }
            _pDataDAO.Update(spInfo);
            return new Result();//DataResult<List<string>>(logoList);
        }
        //填写母板的默认图标文件ID
        public  int SaveProductDefaultLogoFileID(int spId,int fileId,bool isEmptyWrite=true)//是否没有才填写
        {
            var spParmaInfo = _pParamDAO.GetListByProductDataID(spId, EnumProductParam_ParamDefault.Yes);
            //母板只有一个
            if (spParmaInfo.Count == 1 && (!isEmptyWrite || isEmptyWrite && spParmaInfo[0].DefaultProductFileID == 0))
            {
                spParmaInfo[0].DefaultProductFileID = fileId;
                _pParamDAO.Update(spParmaInfo[0]);
            }
            return 1;
        }
        //保存商品基本信息
        public IResult SaveProductParamList(int spId, int dcType, int spParamSum, List<ProductParam> spParamList)
        {
            if (dcType == 0)//无属性:删除已有的非母板子产品
            {
                using (var conn = ConnectionFactory.CreateConnection())
                {
                    conn.Open();
                    var trans = conn.BeginTransaction();
                    try
                    {
                        _pParamDAO.DeleteByProductDataID(spId);
                        //调整总库存
                        var paramInfo = _pParamDAO.GetListByProductDataID(spId, EnumProductParam_ParamDefault.Yes)[0];
                        _UpdateTotal(spId, paramInfo.Stock, spParamSum, trans);
                        trans.Commit();
                        return new Result();
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        throw (ex);
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
            else
            {
                if (spId != spParamList[0].ProductDataID)
                {
                    return new Result(ResultCode.ParameterError);
                }
                var mbInfo = _pParamDAO.GetListByProductDataID(spId, EnumProductParam_ParamDefault.Yes)[0];
                using (var conn = ConnectionFactory.CreateConnection())
                {
                    conn.Open();
                    var trans = conn.BeginTransaction();
                    try
                    {
                        _pParamDAO.DeleteByProductDataID(spId, trans);
                        _pParamDAO.Insert(spParamList, trans);
                        //计算总库存 与 属性个数 一起写入ProductData表(TotalStock、ParamSum)
                        var totalStock = spParamList.Sum(p => p.Stock);
                        _UpdateTotal(spId, totalStock, spParamSum, trans);
                        //母板库存 修改为总库存                        
                        mbInfo.Stock = totalStock;
                        _pParamDAO.Update(mbInfo, trans);
                        trans.Commit();
                        return new Result();
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        throw (ex);
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
        }
        //调整总库存及属性个数
        private int _UpdateTotal(int spId, int totalStock, int paramSum, IDbTransaction trans = null)
        {
            var pDataInfo = _pDataDAO.GetInfo(spId);
            if (pDataInfo != null)
            {
                pDataInfo.TotalStock = totalStock;
                pDataInfo.ParamSum = paramSum;
                _pDataDAO.Update(pDataInfo, trans);
                return 1;
            }
            return 0;
        }
        //保存商品富文本
        public IResult SaveProductHtml(int spId,string html)
        {
            var spInfo = _pDataDAO.GetInfo(spId);
            spInfo.ProductInfo = html;
            _pDataDAO.Update(spInfo);
            Regex regex = new Regex(@"[\w]{32}.[a-zA-Z]{3,4}");
            MatchCollection mc = regex.Matches(html);
            var nList = new List<string>();//本次要保存的图片名称列表
            foreach(var name in mc)
            {
                nList.Add(name.ToString());
            }
            var list = _pFileDAO.GetListBySpID(spId, (int)EnumProductFile_FileType.Image, (int)EnumProductFile_ViewLogo.Html);
            var oList = list.Select(pf => pf.FileName).ToList<string>();//已经上传的图片名称列表
            var delList = oList.Except(nList).ToList();//计算要删除的已上传图片
            foreach(var fn in delList) {
                _FileServer.DeleteSpFile(spId.ToString(), fn, EnumProductFile_ViewLogo.Html);
                _pFileDAO.Delete(spId, fn);
            }
            return new Result();
        }
        //设置商品状态
        public IResult SetProductState(int spId,int state)
        {
            var spInfo = _pDataDAO.GetInfo(spId);
            if (spInfo == null)
            {
                return new Result(ResultCode.RecordNotExist);
            }
            spInfo.ProductState = state;
            _pDataDAO.Update(spInfo);
            return new Result();
        }
        //获取商品介绍：富文本内容
        public IResult GetProductHtml(int spId)
        {
            var pDataInfo = _pDataDAO.GetInfo(spId);
            if (pDataInfo == null)
            {
                return new Result(ResultCode.RecordNotExist);
            }
            return new DataResult<string>(pDataInfo.ProductInfo);
        }
        //获取商品分页列表
        public IResult GetSpList(int PageIndex,int PageSize,string WhereC=null)
        {
            var list= _pDataDAO.GetListOfProduct(PageIndex, PageSize,WhereC);
            var result = new
            {
                url_base = HttpBaseUrl,
                page_data=list
            };
            return new DataResult<dynamic>(result);
        }
        //获取商品卡片分页列表
        public IResult GetSpCardList(int PageIndex, int PageSize, string WhereC = null)
        {
            var list = _pDataDAO.GetListOfProductCard(PageIndex, PageSize, WhereC);
            var result = new
            {
                url_base = HttpBaseUrl,
                page_data = list
            };
            return new DataResult<dynamic>(result);
        }
        //获取商品编辑信息
        public IResult GetProductEditInfo(int spId)
        {            
            var spInfo = new ProductDataDAO().GetEditInfo(spId);
            var picList = new ProductFileDAO().GetListBySpID(spId,(int)EnumProductFile_FileType.Image, (int)EnumProductFile_ViewLogo.Yes);//取展示图片名列表
            var result = new ObjProductEditInfo
            {
                //商品基本数据
                SpHead = spInfo,
                //商品介绍
                SpHtml=spInfo.ProductInfo,
                //商品展示图片列表
                HttpHead = HttpBaseUrl+ @"/product",//图片基址
                SpShowPicList = picList.OrderBy(logo => logo.ViewOrder).Select(logo => logo.FileName).ToList(),                
            };
            return new DataResult<ObjProductEditInfo>(result);
        }        
        //获取商品展示图片列表
        public IResult GetProductShowPicList(int spId)
        {
            var picList = new ProductFileDAO().GetListBySpID(spId,(int)EnumProductFile_FileType.Image,(int)EnumProductFile_ViewLogo.Yes);//取展示图片名列表
            List<string> SpShowPicList = picList.Select(pic =>pic.FileName).ToList();
            var result = new ObjProductLogoList
            {
                HttpHead = HttpBaseUrl + @"/product",
                LogoList = SpShowPicList
            };
            return new DataResult<ObjProductLogoList>(result);
        }
        //获取商品图标列表
        public IResult GetProductLogoSelectList(int spId)
        {
            var picList = new ProductFileDAO().GetListBySpID(spId, (int)EnumProductFile_FileType.Image, (int)EnumProductFile_ViewLogo.Yes);//取展示图片名列表
            var result = new List<ObjProductLogo>();
            picList.ForEach(pic =>
            {
                result.Add(new ObjProductLogo
                {
                    ProductFileID = pic.ProductFileID,
                    Url = HttpBaseUrl + $@"/product/{spId}/5/" + pic.FileName
                });
            });
            return new DataResult<List<ObjProductLogo>>(result);
        }
        //获取商品属性参数列表
        public IResult GetProductAttrParamList(int spId)
        {
            var list= _pParamDAO.GetListByProductDataID(spId,EnumProductParam_ParamDefault.No);//非母板
            var result = new
            {
                SpAttrParams = _GetSpParamList(list),
                param_list = list
            };
            return new DataResult<dynamic>(result);
        }
        private ObjProductParam _GetSpParamList(List<ProductParam> list)
        {
            var attrList = new List<ObjProductAttrible>();
            int paramNum = 0;//无属性
            int n = list.Where(p => !string.IsNullOrEmpty(p.ParamName1) && !string.IsNullOrEmpty(p.ParamName2) && !string.IsNullOrEmpty(p.ParamName3)).Count();
            if (n > 0)
            {
                paramNum = 3;//3个属性
                attrList.Add(new ObjProductAttrible
                {
                    Name = list[0].ParamName1,
                    Values = list.Select(p => p.ParamValue1).Distinct().ToList()
                });
                attrList.Add(new ObjProductAttrible
                {
                    Name = list[0].ParamName2,
                    Values = list.Select(p => p.ParamValue2).Distinct().ToList()
                });
                attrList.Add(new ObjProductAttrible
                {
                    Name = list[0].ParamName3,
                    Values = list.Select(p => p.ParamValue3).Distinct().ToList()
                });
            }
            else
            {
                n = list.Where(p => !string.IsNullOrEmpty(p.ParamName1) && !string.IsNullOrEmpty(p.ParamName2)).Count();
                if (n > 0)
                {
                    paramNum = 2;//2个属性
                    attrList.Add(new ObjProductAttrible
                    {
                        Name = list[0].ParamName1,
                        Values = list.Select(p => p.ParamValue1).Distinct().ToList()
                    });
                    attrList.Add(new ObjProductAttrible
                    {
                        Name = list[0].ParamName2,
                        Values = list.Select(p => p.ParamValue2).Distinct().ToList()
                    });
                }
                else
                {
                    n = list.Where(p => !string.IsNullOrEmpty(p.ParamName1)).Count();
                    if (n > 0)
                    {
                        paramNum = 1;//1个属性
                        attrList.Add(new ObjProductAttrible
                        {
                            Name = list[0].ParamName1,
                            Values = list.Select(p => p.ParamValue1).Distinct().ToList()
                        });
                    }
                }
            }
            var param = new ObjProductParam
            {
                AttrType = paramNum,
                Attrible = attrList
            };
            return param;
        }
        //获取商品种类选择列表
        public IResult GetProductKindSelectList(EnumProductData_ProductType prodType)
        {
            var list = _pKindDAO.GetListByType(prodType,-1,(int)EnumProductKind_KindState.Valid);//获取指定类型的各级所有有效商品种类列表
            var oneLevelList = list.Where(k => k.KindLevel == 1).Select(k=>new ObjProductKindSelect {ProductKindID= k.ProductKindID,KindName= k.KindName }).ToList();//取出一级
            oneLevelList.ForEach(k => {
                var r = list.Where(kd => (kd.ProductKindID ^ k.ProductKindID) > 0 && (kd.ProductKindID ^ k.ProductKindID) < 1000).ToList();
                k.Children = r.Select(kd => new ObjProductKindSelect { ProductKindID = kd.ProductKindID, KindName = kd.KindName }).ToList();
            });
            return new DataResult<List<ObjProductKindSelect>>(oneLevelList);
        }
        //获取商品种类编辑列表
        public IResult GetProductKindEditList(EnumProductData_ProductType prodType,EnumProductKind_KindLevel level)
        {
            var list = _pKindDAO.GetListByType(prodType);//获取指定类型的各级所有种类列表
            var oneLevelList = list.Where(k => k.KindLevel == 1).ToList();//获取指定类型的各级所有种类列表
            var result = new List<dynamic>();
            oneLevelList.ForEach(k => {
                var r = list.Where(kd => (kd.ProductKindID ^ k.ProductKindID) > 0 && (kd.ProductKindID ^ k.ProductKindID) < 1000).ToList();
                result.Add(new
                {
                    record = k,
                    child = r
                });
            });
            return new DataResult<List<dynamic>>(result);
        }
        //获取添加商品种类初始信息
        public IResult GetProductKindAddInitInfo(EnumProductData_ProductType prodType)
        {
            var list = _pKindDAO.GetListByType(prodType);//获取指定类型的各级所有种类列表
            if (list.Count == 0)
            {
                return new DataResult<dynamic>(new {
                    one_level_next_id = 1101000,//最一个ID
                    one_level_next_order=1,//第一个序号
                    next_two_level_id_list = new List<ObjProductKindNextLevelID>(),
                    one_level_list = new List<ObjProductKindSelect>() //用于选择组件
                });
            }
            var oneLevelList = list.Where(k => k.KindLevel == 1).Select(k => new ObjProductKindSelect { ProductKindID = k.ProductKindID, KindName = k.KindName }).ToList();//获取所有一级ID
            var oneLevelIDMax = list.Where(k => k.KindLevel == 1).Max(p => p.ProductKindID);//获取一级的最大ID
            var nextOneLevelID = (oneLevelIDMax / 1000 + 1) * 1000;//计算下一个一级ID
            var oneLevelOrderMax = list.Where(k => k.KindLevel == 1).Max(p => p.OrderNum);//获取一级的最大顺序号
            var nextOneLevelOrder = oneLevelOrderMax + 1;//计算下一个一级顺序号
            //获取每级下一个二级ID
            var nextTwoLevelIDList = new List<ObjProductKindNextLevelID>();
            oneLevelList.ForEach(k =>
            {                
                var twoLevelIDMax = list.Where(c => c.ProductKindID/1000 == k.ProductKindID/1000).Max(p => p.ProductKindID);//该级的最大ID
                var nextTwoLevelID = ++twoLevelIDMax;//计算下一个二级ID
                var twoList = list.Where(c => c.ProductKindID % 1000 > 0 && (c.ProductKindID / 1000 == k.ProductKindID / 1000)).ToList();
                var twoLevelOrderMax = 0;
                if (twoList.Count > 0)
                {
                    twoLevelOrderMax = twoList.Max(p => p.OrderNum);//该级的最大顺序号
                }                
                var nextTwoOrder = ++twoLevelOrderMax;//计算下一个二级顺序号
                nextTwoLevelIDList.Add(new ObjProductKindNextLevelID
                {
                    OneLevelID = k.ProductKindID,
                    NextTwoLevelID = nextTwoLevelID,
                    NextTwoLevelOrder=nextTwoOrder
                });
            });
            return new DataResult<dynamic>(new
            {
                one_level_next_id = nextOneLevelID,//下一个一级ID
                one_level_next_order=nextOneLevelOrder,//下一个一级order
                next_two_level_id_list = nextTwoLevelIDList,                
                one_level_list = oneLevelList //用于选择组件
            });
        }
        //保存新增或修改后的商品种类信息
        public IResult SaveProductKind(ProductKind pKind,bool isAdd)
        {
            if (isAdd)
            {
                //检查是否有商品种类添加权
                //添加
                _pKindDAO.Insert(pKind);
            }
            else
            {
                //检查是否有商品种类修改权
                //更新
                _pKindDAO.Update(pKind);
            }
            return new Result();
        }
        //获取商城首页各类列表 - Business
        public IResult GetMarketList()
        {
            //置顶商品单独读取
            //(1)必买商品
            //(2)活动商品
            //(3)推荐商品
            //(4)热销商品
            //(5)品牌商品
            //(6)新上商品
            return new Result();
        }
    }
}
